package com.punai.customer.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punai.common.utils.SecurityUtils;
import com.punai.common.utils.StringUtils;
import com.punai.customer.domain.CusLinkFeature;
import com.punai.customer.domain.CusMaterialChapter;
import com.punai.customer.domain.CusMaterialItem;
import com.punai.customer.domain.bo.CusLinkFeatureBo;
import com.punai.customer.domain.bo.CusMaterialItemBo;
import com.punai.customer.domain.bo.StaClFeeBo;
import com.punai.customer.domain.contants.CusConstants;
import com.punai.customer.domain.request.CusMaterialItemRequest;
import com.punai.customer.domain.request.CusRewriteCodeRequest;
import com.punai.customer.domain.vo.CusLinkStaVo;
import com.punai.customer.mapper.*;
import com.punai.customer.service.ICusMaterialItemService;
import com.punai.gk.domain.vo.SimplifyVo;
import com.punai.standard.mapper.StaClFeeMapper;
import com.punai.standard.mapper.StaVersionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 材料费用项Service业务层处理
 *
 * @author zxw
 * @date 2022-12-04
 */
@Service
public class CusMaterialItemServiceImpl extends ServiceImpl<CusMaterialItemMapper,CusMaterialItem> implements ICusMaterialItemService
{
    @Autowired
    private CusMaterialItemMapper cusMaterialItemMapper;
    @Autowired
    private StaClFeeMapper staClFeeMapper;
    @Autowired
    private CusMaterialChapterMapper cusMaterialChapterMapper;
    @Autowired
    private CusLinkMaterialStaCusMapper staCusMapper;
    @Autowired
    private CusMaterialCuItemMapper cusMaterialCuItemMapper;
    @Autowired
    private StaVersionMapper staVersionMapper;
    @Autowired
    private CusLinkFeatureMapper cusLinkFeatureMapper;
    /**
     * 查询材料费用项
     *
     * @param id 材料费用项主键
     * @return 材料费用项
     */
    @Override
    public CusMaterialItemBo selectCusMaterialItemById(String id,Long companyId)
    {
        CusMaterialItemBo cusMaterialItemBo = new CusMaterialItemBo();
        cusMaterialItemBo.setCusMaterialItem(cusMaterialItemMapper.selectCusMaterialItemById(id, companyId));
        cusMaterialItemBo.setCusLinkStaVoList(cusMaterialCuItemMapper.selectByCusId(id, companyId));
        List<String> ids = new ArrayList<>(1);
        ids.add(id);
        // 关联特征
        List<CusLinkFeatureBo> cusLinkFeatureBos = cusLinkFeatureMapper.selectLinkFeatureByItemIds(companyId, ids);
        for (CusLinkFeatureBo cusLinkFeatureBo : cusLinkFeatureBos) {
            cusLinkFeatureBo.setItemNames(CollUtil.toList(cusLinkFeatureBo.getFeatureValues().split("\\|")));
        }
        cusMaterialItemBo.setCusLinkFeatureList(cusLinkFeatureBos);
        return cusMaterialItemBo;
    }

    /**
     * 查询材料费用项列表
     *
     * @param cusMaterialItem 材料费用项
     * @return 材料费用项
     */
    @Override
    public List<CusMaterialItem> selectCusMaterialItemList(CusMaterialItem cusMaterialItem)
    {
        Long companyId = cusMaterialItem.getCompanyId();
        List<CusMaterialItem> cusMaterialItems = cusMaterialItemMapper.selectCusMaterialItemList(cusMaterialItem);
        if(CollUtil.isNotEmpty(cusMaterialItems)){
            List<String> ids = cusMaterialItems.stream().map(CusMaterialItem::getId).collect(Collectors.toList());
            List<SimplifyVo> simplifyVos = cusLinkFeatureMapper.selectLinkFeature(companyId, ids);
            Map<String, String> linkFeatureMap = simplifyVos.stream().collect(Collectors.toMap(SimplifyVo::getId, SimplifyVo::getName));
            cusMaterialItems.forEach(e -> e.setLinkFeatures(linkFeatureMap.get(e.getId())));
        }
        return cusMaterialItems;
    }

    /**
     * 新增材料费用项
     *
     * @param cusMaterialItemRequest.cusMaterialItem 材料费用项
     * @return 结果
     */
    @Override
    @Transactional
    public int insertCusMaterialItem(CusMaterialItemRequest cusMaterialItemRequest)
    {
        Long companyId = SecurityUtils.getCompanyId();
        CusMaterialItem cusMaterialItem = cusMaterialItemRequest.getCusMaterialItem();
        if(StringUtils.isEmpty(cusMaterialItem.getChapterId())){
            throw new RuntimeException("未选择章节");
        }
        if(StringUtils.isEmpty(cusMaterialItem.getItemName())){
            throw new RuntimeException("未输入名称");
        }
        if(StringUtils.isEmpty(cusMaterialItem.getUnit())){
            throw new RuntimeException("未输入单位");
        }
        cusMaterialItem.setCompanyId(companyId);
        CusMaterialChapter cusMaterialChapter = cusMaterialChapterMapper.selectCusMaterialChapterById(cusMaterialItem.getChapterId(), companyId);
        if(cusMaterialChapter == null){
            throw new RuntimeException("章节不存在");
        }
        if (cusMaterialItem.getOrderNum() == null) {
            Integer orderNum = getMaxOrderNumByChapterId(cusMaterialItem.getChapterId(), companyId);
            cusMaterialItem.setOrderNum(orderNum + 1);
        }
        int insertMsg = cusMaterialItemMapper.insert(cusMaterialItem);
        if(insertMsg > 0){
            List<CusLinkFeature> cusLinkFeatureList = cusMaterialItemRequest.getCusLinkFeatureList();
            if(CollUtil.isNotEmpty(cusLinkFeatureList)){
                for (CusLinkFeature cusLinkFeature : cusLinkFeatureList) {
                    cusLinkFeature.setCompanyId(companyId);
                    cusLinkFeature.setItemId(cusMaterialItem.getId());
                }
                cusLinkFeatureMapper.insertBatchSomeColumn(cusLinkFeatureList);
            }
        }else {
            throw new RuntimeException("新增失败");
        }
        return 200;
    }

    private Integer getMaxOrderNumByChapterId(String chapterId,Long companyId) {
        return cusMaterialItemMapper.getMaxOrderNumByChapterId(chapterId,companyId);
    }

    /**
     * 修改材料费用项
     *
     * @param cusMaterialItemBo 材料费用项
     * @return 结果
     */
    @Override
    @Transactional
    public int updateCusMaterialItem(CusMaterialItemRequest cusMaterialItemRequest)
    {
        Long companyId = SecurityUtils.getCompanyId();
        CusMaterialItem cusMaterialItem = cusMaterialItemRequest.getCusMaterialItem();
        List<CusLinkStaVo> cusLinkStaVoList = cusMaterialItemRequest.getCusLinkStaVoList();
        List<CusLinkFeature> cusLinkFeatureList = cusMaterialItemRequest.getCusLinkFeatureList();
        String cusId = cusMaterialItem.getId();

        // 处理换算系数
        List<String> linkStaIds = cusLinkStaVoList.stream().map(CusLinkStaVo::getId).collect(Collectors.toList());
        staCusMapper.deleteByNotInId(companyId,cusId,linkStaIds);
        if(CollUtil.isNotEmpty(cusLinkStaVoList)){
            for (CusLinkStaVo cusLinkStaVo : cusLinkStaVoList) {
                staCusMapper.updateCoefficient(companyId,cusLinkStaVo);
            }
        }

        // 处理关联特征
        List<String> ids = new ArrayList<>(1);
        ids.add(cusId);
        cusLinkFeatureMapper.deleteByItemIds(companyId,ids);

        if(CollUtil.isNotEmpty(cusLinkFeatureList)){
            for (CusLinkFeature cusLinkFeature : cusLinkFeatureList) {
                cusLinkFeature.setCompanyId(companyId);
                cusLinkFeature.setItemId(cusMaterialItem.getId());
            }
            cusLinkFeatureMapper.insertBatchSomeColumn(cusLinkFeatureList);
        }

        LambdaQueryWrapper<CusMaterialItem> wrapper = Wrappers.<CusMaterialItem>lambdaQuery()
                .eq(CusMaterialItem::getCompanyId, companyId)
                .eq(CusMaterialItem::getId, cusId);
        cusMaterialItemMapper.update(cusMaterialItem,wrapper);
        return 200;
    }

    /**
     * 批量删除材料费用项
     *
     * @param ids 需要删除的材料费用项主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteCusMaterialItemByIds(List<String> ids,Long companyId)
    {
        int i = cusMaterialItemMapper.deleteCusMaterialItemByIds(ids, companyId);
        if (i > 0) {
            staCusMapper.deleteLinkByCusId(ids,companyId);
        }
        return i;
    }

    @Override
    @Transactional
    public int moveToChapter(String[] ids, String chapterId, Long companyId) {
        // 移动章节
        cusMaterialItemMapper.updateChapterIdByIds(ids,chapterId,companyId);
        return 1;
    }

    @Override
    public Long countChapterIdIsZero(Long companyId) {
        return cusMaterialItemMapper.selectCount(new LambdaQueryWrapper<CusMaterialItem>().eq(CusMaterialItem::getCompanyId,companyId).eq(CusMaterialItem::getChapterId,CusConstants.CHAPTER_ID_NULL));
    }

    @Override
    @Transactional
    public int rewriteCode(CusRewriteCodeRequest codeRequest) {
        Long companyId = SecurityUtils.getCompanyId();
        int countNotAllot = cusMaterialItemMapper.countNotAllot(companyId, CusConstants.CHAPTER_ID_NULL);
        if (countNotAllot != 0) {
            throw new RuntimeException("存在未分配章节的费用项");
        }
        Integer suffixLen = codeRequest.getSuffixLen();
        Integer maxCountLen = cusMaterialItemMapper.countByChapterId(companyId);
        if(suffixLen < maxCountLen){
            throw new RuntimeException("根据费用项数量统计,编码后缀不能少于" + maxCountLen + "位");
        }
        cusMaterialItemMapper.rewriteMaterialCode(companyId,codeRequest.getPrefix(),suffixLen);
        return 1;
    }

    @Override
    public List<CusMaterialItem> validateCode(Long companyId) {
        int countNotAllot = cusMaterialItemMapper.countNotAllot(companyId, CusConstants.CHAPTER_ID_NULL);
        if (countNotAllot != 0) {
            throw new RuntimeException("存在未分配章节的费用项");
        }
        List<CusMaterialItem> cusMaterialItems = new ArrayList<>();
        LambdaQueryWrapper<CusMaterialItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CusMaterialItem::getCompanyId, companyId);
        wrapper.groupBy(CusMaterialItem::getCode);
        wrapper.having("count(*) > 1 or `code`='' or ISNULL(`code`)");
        cusMaterialItems = cusMaterialItemMapper.selectList(wrapper);
        return cusMaterialItems;
    }

    @Override
    public StaClFeeBo getStaMaterialItemById(String id, Long companyId) {
        String newestId = staVersionMapper.getNewestId(companyId,CusConstants.CL_TYPE,null);
        StaClFeeBo staClFeeBo = new StaClFeeBo();
        staClFeeBo.setStaClFee(staClFeeMapper.selectStaClFeeById(newestId, id));
        staClFeeBo.setCusMaterialCuItemList(cusMaterialCuItemMapper.selectByCusIdSta(id, companyId, newestId));
        return staClFeeBo;
    }

}
